<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html><head>
<meta content="uft-8" name="charset">

<title>Microservices</title>
<meta http-equiv="Content-type" content="text/html; charset=UTF-8">
<meta content="summary_large_image" name="twitter:card">

<meta content="16665197" name="twitter:site:id">

<meta content="@martinfowler" name="twitter:site">

<meta content="@boicy" name="twitter:creator">

<meta content="Microservices" property="og:title">

<meta content="../articles/microservices.html" property="og:url">

<meta content="Defining the microservices architectural style by describing their nine common characteristics" property="og:description">

<meta content="../microservices_files/card.png" property="og:image">

<meta content="martinfowler.com" property="og:site_name">

<meta content="article" property="og:type">

<meta content="2014-03-25" property="og:article:modified_time">

<meta content="@boicy" name="twitter:creator">

<meta content="width=device-width, initial-scale=1" name="viewport">

<link href="microservices_files/microservices.css" rel="stylesheet" type="text/css">
<meta http-equiv="origin-trial" content="AymqwRC7u88Y4JPvfIF2F37QKylC04248hLCdJAsh8xgOfe/dVJPV3XS3wLFca1ZMVOtnBfVjaCMTVudWM//5g4AAAB7eyJvcmlnaW4iOiJodHRwczovL3d3dy5nb29nbGV0YWdtYW5hZ2VyLmNvbTo0NDMiLCJmZWF0dXJlIjoiUHJpdmFjeVNhbmRib3hBZHNBUElzIiwiZXhwaXJ5IjoxNjk1MTY3OTk5LCJpc1RoaXJkUGFydHkiOnRydWV9"><style type="text/css">@font-face { font-family: TencentSans; src: url("moz-extension://7ebec3f3-df69-44bd-9f24-2f7e0d7027ee/static/fonts/TencentSans.woff2"); }</style></head>

<body><header id="banner" style="background-image: url(&quot;/img/zakim.png&quot;); background-repeat: no-repeat">

<div class="name-logo"><a href="https://martinfowler.com/"><img src="../mf-name-white.png"></a></div>
  <div class="search">
    <!-- SiteSearch Google -->
    <form method="GET" action="https://www.google.com/search">
      <input type="hidden" name="ie" value="UTF-8">
      <input type="hidden" name="oe" value="UTF-8">
      <input class="field" type="text" name="q" size="15" maxlength="255">
      <button class="button" type="submit" name="btnG" value=" " title="Search">
      <input type="hidden" name="domains" value="martinfowler.com">
      <input type="hidden" name="sitesearch" value=""> 
      <input type="hidden" name="sitesearch" value="martinfowler.com">
    
  </button></form></div>

<div class="menu-button navmenu-button"><a class="icon icon-bars" href="#navmenu-bottom"></a></div>

<nav class="top-menu">
<ul>
<li><a class="" href="https://refactoring.com/">Refactoring</a></li>

<li><a class="" href="https://martinfowler.com/agile.html">Agile</a></li>

<li><a class="" href="https://martinfowler.com/architecture">Architecture</a></li>

<li><a class="" href="https://martinfowler.com/aboutMe.html">About</a></li>

<li><a class="tw" href="https://www.thoughtworks.com/">Thoughtworks</a></li>

<li><a class="icon icon-rss" href="https://martinfowler.com/feed.atom" title="feed"></a></li>

<li><a class="icon icon-twitter" href="https://www.twitter.com/martinfowler" title="Twitter stream"></a></li>

<li class="icon"><a href="https://toot.thoughtworks.com/@mfowler" title="Mastodon stream"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M433 179.11c0-97.2-63.71-125.7-63.71-125.7-62.52-28.7-228.56-28.4-290.48 0 0 0-63.72 28.5-63.72 125.7 0 115.7-6.6 259.4 105.63 289.1 40.51 10.7 75.32 13 103.33 11.4 50.81-2.8 79.32-18.1 79.32-18.1l-1.7-36.9s-36.31 11.4-77.12 10.1c-40.41-1.4-83-4.4-89.63-54a102.54 102.54 0 0 1-.9-13.9c85.63 20.9 158.65 9.1 178.75 6.7 56.12-6.7 105-41.3 111.23-72.9 9.8-49.8 9-121.5 9-121.5zm-75.12 125.2h-46.63v-114.2c0-49.7-64-51.6-64 6.9v62.5h-46.33V197c0-58.5-64-56.6-64-6.9v114.2H90.19c0-122.1-5.2-147.9 18.41-175 25.9-28.9 79.82-30.8 103.83 6.1l11.6 19.5 11.6-19.5c24.11-37.1 78.12-34.8 103.83-6.1 23.71 27.3 18.4 53 18.4 175z"></path></svg></a></li>
</ul>
</nav>
</header>
<nav id="top-navmenu">
<nav class="navmenu">
<div class="nav-head">  <div class="search">
    <!-- SiteSearch Google -->
    <form method="GET" action="https://www.google.com/search">
      <input type="hidden" name="ie" value="UTF-8">
      <input type="hidden" name="oe" value="UTF-8">
      <input class="field" type="text" name="q" size="15" maxlength="255">
      <button class="button" type="submit" name="btnG" value=" " title="Search">
      <input type="hidden" name="domains" value="martinfowler.com">
      <input type="hidden" name="sitesearch" value=""> 
      <input type="hidden" name="sitesearch" value="martinfowler.com">
    
  </button></form></div>

<div class="closediv">
<span class="close" title="close"></span>
</div>
</div>

<div class="nav-body">
<div class="topics">
<h2>Topics</h2>

<p><a href="https://martinfowler.com/architecture">Architecture</a></p>

<p><a href="https://refactoring.com/">Refactoring</a></p>

<p><a href="https://martinfowler.com/agile.html">Agile</a></p>

<p><a href="https://martinfowler.com/delivery.html">Delivery</a></p>

<p><a href="https://martinfowler.com/microservices">Microservices</a></p>

<p><a href="https://martinfowler.com/data">Data</a></p>

<p><a href="https://martinfowler.com/testing">Testing</a></p>

<p><a href="https://martinfowler.com/dsl.html">DSL</a></p>
</div>

<div class="about">
<h2>about me</h2>

<p><a href="https://martinfowler.com/aboutMe.html">About</a></p>

<p><a href="https://martinfowler.com/books">Books</a></p>

<p><a href="https://martinfowler.com/faq.html">FAQ</a></p>
</div>

<div class="content">
<h2>content</h2>

<p><a href="https://martinfowler.com/videos.html">Videos</a></p>

<p><a href="https://martinfowler.com/tags">Content Index</a></p>

<p><a href="https://martinfowler.com/articles/eurogames">Board Games</a></p>

<p><a href="https://martinfowler.com/photos">Photography</a></p>
</div>

<div class="tw">
<h2>Thoughtworks</h2>

<p><a href="https://thoughtworks.com/insights">Insights</a></p>

<p><a href="https://thoughtworks.com/careers">Careers</a></p>

<p><a href="https://thoughtworks.com/products">Products</a></p>
</div>

<div class="feeds">
<h2>follow</h2>

<p><a href="https://www.twitter.com/martinfowler">Twitter</a></p>

<p><a href="https://martinfowler.com/feed.atom">RSS</a></p>

<p><a href="https://toot.thoughtworks.com/@mfowler">Mastodon</a></p>
</div>
</div>
</nav>
</nav>

<nav id="toc-dropdown">
<button class="dropdown-button">
<h2>Table of Contents</h2>
</button>

<div class="hidden" id="dropdownLinks">
<ul>
<li><a href="#top">Top</a></li>

<li><a href="#CharacteristicsOfAMicroserviceArchitecture">Characteristics of a Microservice Architecture</a>
<ul>
<li><a href="#ComponentizationViaServices">Componentization via Services</a></li>

<li><a href="#OrganizedAroundBusinessCapabilities">Organized around Business Capabilities</a></li>

<li><a href="#ProductsNotProjects">Products not Projects</a></li>

<li><a href="#SmartEndpointsAndDumbPipes">Smart endpoints and dumb pipes</a></li>

<li><a href="#DecentralizedGovernance">Decentralized Governance</a></li>

<li><a href="#DecentralizedDataManagement">Decentralized Data Management</a></li>

<li><a href="#InfrastructureAutomation">Infrastructure Automation</a></li>

<li><a href="#DesignForFailure">Design for failure</a></li>

<li><a href="#EvolutionaryDesign">Evolutionary Design</a></li>
</ul>
</li>

<li><a href="#AreMicroservicesTheFuture">Are Microservices the Future?</a></li>
</ul>

<h3>Sidebars</h3>

<ul>
<li><a href="#HowBigIsAMicroservice">How big is a microservice?</a></li>

<li><a href="#MicroservicesAndSoa">Microservices and SOA</a></li>

<li><a href="#ManyLanguagesManyOptions">Many languages, many options</a></li>

<li><a href="#Battle-testedStandardsAndEnforcedStandards">Battle-tested standards and enforced standards</a></li>

<li><a href="#MakeItEasyToDoTheRightThing">Make it easy to do the right thing</a></li>

<li><a href="#TheCircuitBreakerAndProductionReadyCode">The circuit breaker and production ready code</a></li>

<li><a href="#SynchronousCallsConsideredHarmful">Synchronous calls considered harmful</a></li>
</ul>
</div>
</nav>

<main>
<h1>Microservices</h1>

<p class="subtitle">a definition of this new architectural term</p>

<p class="subtitle">定义这个新的架构术语</p>

<section class="frontMatter">
<p class="abstract"><i>
    The term "Microservice Architecture" has sprung up over the
    last few years to describe a particular way of designing software
    applications as suites of independently deployable services. While
    there is no precise definition of this architectural style, there
    are certain common characteristics around organization around
    business capability, automated deployment, intelligence in the
    endpoints, and decentralized control of languages and data.
  </i></p>

<p class="abstract"><i>
    "微服务架构"（Microservice Architecture）这个术语在过去几年里突然出现，用来描述一种特定的软件应用程序设计方式，
    即将应用程序设计为一套独立可部署的服务集合。
    尽管这种架构风格没有精确的定义，
    但是围绕业务能力组织、
    自动化部署、
    端点的智能
    以及语言和数据的去中心化控制等方面，
    存在着一些共同的特征。
  </i></p>

<p class="date">25 March 2014</p>
<hr>
<div class="front-grid">
<div class="author-list">
<div class="author">
<div class="photo"><a href="https://twitter.com/boicy"><img alt="Photo of James Lewis" src="microservices_files/jlewis.jpg" width="80"></a></div>

<address class="name"><a href="https://twitter.com/boicy" rel="author">James Lewis</a></address>

<div class="bio">
<p>James Lewis is a Principal Consultant at Thoughtworks and
      member of the Technology Advisory Board. James' interest in
      building applications out of small collaborating services stems
      from a background in integrating enterprise systems at scale.
      He's built a number of systems using microservices and has been
      an active participant in the growing community for a couple of
      years.</p>

<p>詹姆斯·刘易斯（James Lewis）是 Thoughtworks 的高级顾问，也是技术顾问委员会的成员。
    詹姆斯对于构建由小型协作服务组成的应用程序的兴趣
    源于他在大规模集成企业系统方面的背景。
    他使用微服务构建了许多系统，
    并在过去几年中一直是这个不断增长的社区中的积极参与者。
</p>

</div>
</div>

<div class="author">
<div class="photo"><a href="https://martinfowler.com/"><img alt="Photo of Martin Fowler" src="../mf.jpg" width="80"></a></div>

<address class="name"><a href="https://martinfowler.com/" rel="author">Martin Fowler</a></address>

<div class="bio">
<p>Martin Fowler is an author, speaker, and general loud-mouth
      on software development. He's long been puzzled by the problem
      of how to componentize software systems, having heard more vague claims
      than he's happy with. He hopes that microservices will live up
      to the early promise its advocates have found.</p>

<p>马丁·福勒（Martin Fowler）是一位作家、演讲者，也是软件开发领域的一位知名的发声者。
    长期以来，他对于如何将软件系统组件化感到困惑，
    因为他听到了太多模糊的宣称，这让他感到不满意。
    他希望微服务能够实现其倡导者所发现的前期承诺。
</p>
</div>
</div>
</div>

<div class="tags">
<p class="tag-link"><a href="https://martinfowler.com/tags/popular.html">popular</a></p>

<p class="tag-link"><a href="https://martinfowler.com/tags/application%20architecture.html">application architecture</a></p>

<p class="tag-link"><a href="https://martinfowler.com/tags/microservices.html">microservices</a></p>
</div>

<div class="contents">
<h2>Contents</h2>

<ul>
<li><a href="#CharacteristicsOfAMicroserviceArchitecture">Characteristics of a Microservice Architecture</a>
<ul>
<li><a href="#ComponentizationViaServices">Componentization via Services</a></li>
<li><a href="#ComponentizationViaServices">通过服务进行组件化</a></li>

<li><a href="#OrganizedAroundBusinessCapabilities">Organized around Business Capabilities</a></li>
<li><a href="#OrganizedAroundBusinessCapabilities">围绕业务能力进行组织</a></li>

<li><a href="#ProductsNotProjects">Products not Projects</a></li>
<li><a href="#ProductsNotProjects">产品而非项目</a></li>

<li><a href="#SmartEndpointsAndDumbPipes">Smart endpoints and dumb pipes</a></li>
<li><a href="#SmartEndpointsAndDumbPipes">智能端点和哑管道</a></li>

<li><a href="#DecentralizedGovernance">Decentralized Governance</a></li>
<li><a href="#DecentralizedGovernance">去中心化治理</a></li>

<li><a href="#DecentralizedDataManagement">Decentralized Data Management</a></li>
<li><a href="#DecentralizedDataManagement">去中心化数据管理</a></li>

<li><a href="#InfrastructureAutomation">Infrastructure Automation</a></li>
<li><a href="#InfrastructureAutomation">基础设施自动化</a></li>

<li><a href="#DesignForFailure">Design for failure</a></li>
<li><a href="#DesignForFailure">设计时考虑失败</a></li>

<li><a href="#EvolutionaryDesign">Evolutionary Design</a></li>
<li><a href="#EvolutionaryDesign">演进式设计</a></li>
</ul>
</li>

<li><a href="#AreMicroservicesTheFuture">Are Microservices the Future?</a></li>
<li><a href="#AreMicroservicesTheFuture">微服务是未来吗?</a></li>
</ul>

<h3>Sidebars</h3>

<ul>
<li><a href="#HowBigIsAMicroservice">How big is a microservice?</a></li>
<li><a href="#HowBigIsAMicroservice">一个微服务有多大?</a></li>

<li><a href="#MicroservicesAndSoa">Microservices and SOA</a></li>
<li><a href="#MicroservicesAndSoa">微服务对比 SOA</a></li>

<li><a href="#ManyLanguagesManyOptions">Many languages, many options</a></li>
<li><a href="#ManyLanguagesManyOptions">多种语言, 多种选择</a></li>

<li><a href="#Battle-testedStandardsAndEnforcedStandards">Battle-tested standards and enforced standards</a></li>
<li><a href="#Battle-testedStandardsAndEnforcedStandards">经过实战测试的标准和强制执行的标准</a></li>

<li><a href="#MakeItEasyToDoTheRightThing">Make it easy to do the right thing</a></li>
<li><a href="#MakeItEasyToDoTheRightThing">让正确的事情变的容易</a></li>

<li><a href="#TheCircuitBreakerAndProductionReadyCode">The circuit breaker and production ready code</a></li>
<li><a href="#TheCircuitBreakerAndProductionReadyCode">断路器和生产就绪代码</a></li>

<li><a href="#SynchronousCallsConsideredHarmful">Synchronous calls considered harmful</a></li>
<li><a href="#SynchronousCallsConsideredHarmful">同步调用被认为是有害的</a></li>
</ul>
</div>
</div>
<hr></section>

<div class="paperBody deep">
<p>"Microservices" - yet another new term on the crowded streets
    of software architecture. Although our natural inclination is to
    pass such things by with a contemptuous glance, this bit of
    terminology describes a style of software systems that we are
    finding more and more appealing. We've seen many projects use this
    style in the last few years, and results so far have been
    positive, so much so that for many of our colleagues this is
    becoming the default style for building enterprise
    applications. Sadly, however, there's not much information that
    outlines what the microservice style is and how to do it.</p>


<p>"微服务"——在软件架构这条熙熙攘攘的大街上，又一个新术语出现了。
    尽管我们本能的反应是对这类新词投以轻蔑的一瞥，
    但这术语描述的软件系统风格却越来越吸引我们的注意。
    在过去几年中，我们已经看到了许多项目采用了这种风格，
    到目前为止，结果都是积极的，
    以至于我们许多同事都开始将微服务作为构建企业应用的首选风格。
    然而，遗憾的是，目前并没有太多信息详细解释微服务风格究竟是什么以及如何实现它。
</p>
    

<p>In short, the microservice architectural style <span class="foot-ref"><a href="#footnote-etymology">[1]</a></span> is an approach
    to developing a single application as a suite of small services,
    each running in its own process and communicating with lightweight
    mechanisms, often an HTTP resource API. These services are built
    around business capabilities and independently deployable by fully
    automated deployment machinery. There is a bare minimum of
    centralized management of these services, which may be written in
    different programming languages and use different data storage
    technologies. </p>


<p>简而言之，微服务架构风格是一种将单个应用程序作为一套小型服务来开发的方法，
    每个服务都在自己的进程中运行，
    并通过轻量级的机制进行通信，通常是通过HTTP资源API。
    这些服务是围绕业务能力构建的，
    可以通过完全自动化的部署机制独立部署。
    这些服务的集中管理最少，
    它们可能用不同的编程语言编写，
    并使用不同的数据存储技术。
</p>



<aside class="sidebar" id="guide-sidebar">
<p><a href="https://martinfowler.com/microservices"><img src="microservices_files/microservices-sq.png"></a></p>

<p>My <a href="https://martinfowler.com/microservices">Microservices Resource
      Guide</a> provides links to the best
      articles, videos, books, and podcasts about microservices.</p>

<p>我的<a href="https://martinfowler.com/microservices">微服务资源指南</a>
    提供了关于微服务的最佳文章、视频、书籍和播客的链接。
</p>
</aside>

<p>To start explaining the microservice style it's useful to
    compare it to the monolithic style: a monolithic application built
    as a single unit. Enterprise Applications are often built in three main parts: a
    client-side user interface (consisting of HTML pages and
    javascript running in a browser on the user's machine) a database
    (consisting of many tables inserted into a common, and usually
    relational, database management system), and a server-side
    application. The server-side application will handle HTTP
    requests, execute domain logic, retrieve and update data from the
    database, and select and populate HTML views to be sent to the
    browser. This server-side application is a <i>monolith</i> - a single
    logical executable<span class="foot-ref"><a href="#footnote-monolith">[2]</a></span>. Any changes to the
    system involve building and deploying a new version of the
    server-side application. </p>

<p>要开始解释微服务风格，将其与单体风格进行比较是有帮助的：
    单体应用程序是作为一个单一单元构建的。
    企业应用程序通常分为三个主要部分：
    客户端用户界面（由在用户机器上的浏览器中运行的HTML页面和javascript组成）、
    数据库（由许多插入到共同的、通常是关系型的数据库管理系统中的表组成），
    以及服务器端应用程序。
    服务器端应用程序将处理HTTP请求、执行领域逻辑、从数据库检索和更新数据，
    以及选择和填充要发送到浏览器的HTML视图。
    这个服务器端应用程序是一个<i>单体</i> —— 一个单一的逻辑可执行文件[2]。
    系统中任何的变更都涉及构建和部署服务器端应用程序的新版本。
 </p>

<p>Such a monolithic server is a natural way to approach building
    such a system. All your logic for handling a request runs in a
    single process, allowing you to use the basic features of your
    language to divide up the application into classes, functions, and
    namespaces. With some care, you can run and test the application
    on a developer's laptop, and use a deployment pipeline to ensure
    that changes are properly tested and deployed into production. You
    can horizontally scale the monolith by running many instances
    behind a load-balancer.</p>

<p>这种单体服务器是构建此类系统的自然方式。
    处理请求的所有逻辑都在一个单一进程中运行，
    允许你使用语言的基本功能将应用程序划分为类、函数和命名空间。
    经过适当的注意，你可以在开发者的笔记本电脑上运行和测试应用程序，
    并使用部署管道来确保变更被适当地测试并部署到生产环境中。
    你可以在负载均衡器后面运行许多实例来水平扩展单体。
</p>


<p>Monolithic applications can be successful, but increasingly
    people are feeling frustrations with them - especially as more
    applications are being deployed to the cloud . Change cycles are
    tied together - a change made to a small part of the application,
    requires the entire monolith to be rebuilt and deployed. Over time
    it's often hard to keep a good modular structure, making it harder
    to keep changes that ought to only affect one module within that
    module. Scaling requires scaling of the entire application rather
    than parts of it that require greater resource. </p>

<p>单体应用程序可能会成功，但越来越多的人对它们感到沮丧
    —— 尤其是随着越来越多的应用程序被部署到云端。
    变更周期是联系在一起的
    —— 对应用程序的一小部分进行的变更，需要整个单体被重新构建和部署。
    随着时间的推移，保持良好的模块化结构通常很难，
    这使得将本应只影响一个模块的变更限制在该模块内变得更加困难。
    扩展需要整个应用程序的扩展，
    而不是只扩展需要更多资源的那部分。
</p>

<div class="figure " id="microservices_images_sketch.png"><img src="microservices_files/sketch.png">
<p class="photoCaption">Figure 1: Monoliths
    and Microservices</p>
</div>

<div class="clear"></div>

<p>These frustrations have led to the microservice architectural
    style: building applications as suites of services. As well as the
    fact that services are independently deployable and scalable, each
    service also provides a firm module boundary, even allowing for
    different services to be written in different programming
    languages. They can also be managed by different teams .</p>

<p>这些挫折导致了微服务架构风格的出现：
    将应用程序构建为一套服务的集合。
    除了服务可以独立部署和扩展之外，
    每个服务还提供了一个明确的模块边界，
    甚至允许不同服务使用不同的编程语言编写。
    它们也可以由不同的团队管理。
</p>

<p>We do not claim that the microservice style is novel
    or innovative, its roots go back at least to the design principles
    of Unix. But we do think that not enough people consider a
    microservice architecture and that many software developments
    would be better off if they used it.</p>

<p>我们不声称微服务风格是新颖的或创新的，它的根源至少可以追溯到Unix的设计原则。
    但我们确实认为，考虑微服务架构的人不够多，
    许多软件开发如果使用了微服务架构会更好。
</p>

<section id="CharacteristicsOfAMicroserviceArchitecture">
<h2>Characteristics of a Microservice Architecture</h2>

<p>We cannot say there is a formal definition of the
      microservices architectural style, but we can attempt to
      describe what we see as common characteristics for architectures
      that fit the label. As with any definition that outlines common
      characteristics, not all microservice architectures have all the
      characteristics, but we do expect that most microservice
      architectures exhibit most characteristics. While we authors
      have been active members of this rather loose community, our
      intention is to attempt a description of what we see in our own
      work and in similar efforts by teams we know of. In particular
      we are not laying down some definition to conform to. </p>

<p>我们无法给出微服务架构风格的正式定义，
    但我们可以尝试描述我们认为符合该标签架构的共同特征。
    与任何描述共同特征的定义一样，
    并非所有微服务架构都具有所有特征，
    但我们确实期望大多数微服务架构展现出大多数特征。
    虽然我们这些作者一直是这个相当松散的社区中的积极成员，
    但我们的意图是尝试描述我们在自己的工作中
    以及我们了解到的类似团队工作中的所见所闻。
    特别是我们并不是在制定一些需要遵循的定义。
</p>

<section id="ComponentizationViaServices">
<h3>Componentization via Services</h3>

<p>For as long as we've been involved in the software
        industry, there's been a desire to build systems by plugging
        together components, much in the way we see things are made in
        the physical world. During the last couple of decades we've
        seen considerable progress with large compendiums of common
        libraries that are part of most language platforms.</p>

<p>自从我们参与软件行业以来，就一直有一种愿望，
那就是希望通过像物理世界中制造事物那样的方式，将组件拼接起来构建系统。
在过去的几十年里，我们已经看到了显著的进步，
大多数语言平台都包含了大量常见库的大合集。
</p>

<p>When talking about components we run into the difficult
        definition of what makes a component. <a href="https://martinfowler.com/bliki/SoftwareComponent.html">Our definition</a> is that a
        <b>component</b> is a unit of software that is
        independently replaceable and upgradeable.</p>

<p>当我们谈论组件时，我们遇到了一个难题，那就是什么构成了一个组件。
    <a href="../bliki/SoftwareComponent.html">我们的定义</a>是，一个<b>组件</b>是一个软件单元，
    它是可以独立替换和升级的。
</p>

<p>Microservice architectures will use libraries, but their
        primary way of componentizing their own software is by
        breaking down into services. We define <b>libraries</b>
        as components that are linked into a program and called using
        in-memory function calls, while <b>services</b> are
        out-of-process components who communicate with a mechanism such
        as a web service request, or remote procedure call. (This is a
        different concept to that of a service object in many OO
        programs <span class="foot-ref"><a href="#footnote-service-object">[3]</a></span>.)</p>


<p>微服务架构将使用库，
    但它们将自己软件组件化的主要方式是通过分解成服务。
    我们将<b>库</b>定义为链接到程序中并通过内存中的函数调用来调用的组件，
    而<b>服务</b>是进程外组件，
    它们通过诸如Web服务请求或远程过程调用等机制进行通信。
    (这与许多面向对象程序中的服务对象概念不同
    <span class="foot-ref"><a href="#footnote-service-object">[3]</a></span>。)
</p>
        

<p>One main reason for using services as components (rather
        than libraries) is that services are independently deployable.
        If you have an application <span class="foot-ref"><a href="#footnote-application">[4]</a></span> that consists of a multiple
        libraries in a single process, a change to any single component
        results in having to redeploy the entire application. But if
        that application is decomposed into multiple services, you can
        expect many single service changes to only require
        that service to be redeployed. That's not an absolute, some
        changes will change service interfaces resulting in some
        coordination, but the aim of a good microservice architecture is
        to minimize these through cohesive service boundaries and
        evolution mechanisms in the service contracts.</p>

<p>使用服务作为组件（而不是库）的一个主要原因是服务是独立可部署的。
    如果您有一个由单个进程中的多个库组成的应用程序<span class="foot-ref"><a href="#footnote-application">[4]</a></span>，
    那么任何一个组件的变更都需要重新部署整个应用程序。
    但是，如果该应用程序被分解为多个服务，
    您可以期望许多单个服务变更只要求重新部署那个服务。
    这并不是绝对的，一些变更会改变服务接口，从而需要一些协调，
    但一个好的微服务架构的目标
    是通过凝聚服务边界
    和服务合同中的演进机制
    来最小化这些变更。
</p>

<p>Another consequence of using services as components is a
        more explicit component interface. Most languages do not have
        a good mechanism for defining an explicit <a href="https://martinfowler.com/bliki/PublishedInterface.html">Published Interface</a>. Often it's only documentation and
        discipline that prevents clients breaking a component's
        encapsulation, leading to overly-tight coupling between
        components. Services make it easier to avoid this by using
        explicit remote call mechanisms.</p>

<p>使用服务作为组件的另一个后果是组件接口更加明确。
    大多数语言没有很好的机制来定义明确的<a href="https://martinfowler.com/bliki/PublishedInterface.html">发布接口</a>。
    通常，只有文档和纪律才能防止客户端破坏组件的封装，
    从而导致组件之间过度紧密的耦合。
    服务通过使用明确的远程调用机制，更容易避免这种情况。
</p>

<p>Using services like this does have downsides. Remote calls
        are more expensive than in-process calls, and thus remote APIs
        need to be coarser-grained, which is often more awkward to
        use. If you need to change the allocation of responsibilities
        between components, such movements of behavior are harder to
        do when you're crossing process boundaries.</p>

<p>像这样使用服务确实有其缺点。
    远程调用比进程内调用更昂贵，
    因此远程API需要更加粗粒度，这通常使用起来更加不便。
    如果您需要更改组件之间责任分配，
    当您跨越进程边界时，这种行为的移动更加困难。
</p>

<p>At a first approximation, we can observe that services map
        to runtime processes, but that is only a first approximation.
        A service may consist of multiple processes that will always
        be developed and deployed together, such as an application
        process and a database that's only used by that service. </p>
</section>

<p>首先，我们可以观察到服务映射到运行时进程，
    但这只是一个初步的近似。
    一个服务可能由多个始终一起开发和部署的进程组成，
    例如一个应用程序进程和一个仅由该服务使用的数据库。
</p>
</section>

<section id="OrganizedAroundBusinessCapabilities">
<h3>Organized around Business Capabilities</h3>

<p>When looking to split a large application into parts,
        often management focuses on the technology layer, leading to
        UI teams, server-side logic teams, and database teams. When
        teams are separated along these lines, even simple changes can
        lead to a cross-team project taking time and budgetary approval. A smart team will
        optimise around this and plump for the lesser of two evils -
        just force the logic into whichever application they have
        access to. Logic everywhere in other words. This is an example
        of <a href="https://martinfowler.com/bliki/ConwaysLaw.html">Conway's Law</a> in action.</p>


<p>当考虑将大型应用程序拆分成几个部分时，
    管理层通常会关注技术层，导致出现UI团队、服务器端逻辑团队和数据库团队。
    当团队按照这些线条分开时，
    即使是简单的变更也可能导致跨团队项目耗费时间和预算审批。
    一个聪明的团队会围绕这个问题进行优化，选择两害相权取其轻的方法
     —— 只是将逻辑强制放入他们可以访问的任何应用程序中。
     换句话说，逻辑无处不在。
     这是<a href="../bliki/ConwaysLaw.html">康威定律</a>的一个实例。
</p>

<blockquote>
<p>Any organization that designs a system (defined broadly)
          will produce a design whose structure is a copy of the
          organization's communication structure.</p>

<p>任何设计系统的组织（广义上定义）都将产生一个其结构为组织沟通结构副本的设计。</p>

<p class="quote-attribution">-- Melvin Conway, 1968</p>
</blockquote>

<div class="figure " id="microservices_images_conways-law.png"><img src="microservices_files/conways-law.png">
<p class="photoCaption">Figure 2: Conway's
        Law in action</p>
</div>

<div class="clear"></div>

<p>The microservice approach to division is different,
        splitting up into services organized around
        <b>business capability</b>. Such services take a
        broad-stack implementation of software for that business area,
        including user-interface, persistant storage, and any external
        collaborations. Consequently the teams are cross-functional,
        including the full range of skills required for the
        development: user-experience, database, and project
        management. </p>

<p>微服务方法的划分方式不同，它是按照<b>业务能力</b>组织成服务的。
    这样的服务采用该业务领域的宽堆栈软件实现，
    包括用户界面、持久存储和任何外部协作。
    因此，这些团队是跨职能的，包括开发所需的全范围技能：用户体验、数据库和项目管理。
</p>

<div class="figure " id="microservices_images_PreferFunctionalStaffOrganization.png"><img src="microservices_files/PreferFunctionalStaffOrganization.png">
<p class="photoCaption">Figure 3: Service
        boundaries reinforced by team boundaries 服务边界被团队边界加强</p>
</div>

<div class="clear"></div>

<aside class="sidebar" id="HowBigIsAMicroservice">
<h3>How big is a microservice?</h3>

<p>Although “microservice” has become a popular name for this
          architectural style, its name does lead to an unfortunate
          focus on the size of service, and arguments about what
          constitutes “micro”. In our conversations with microservice
          practitioners, we see a range of sizes of services. The
          largest sizes reported follow Amazon's notion of the
          <a href="https://martinfowler.com/bliki/TwoPizzaTeam.html">Two Pizza Team</a>
          (i.e. the whole team can be fed by two pizzas),
          meaning no more than a dozen people. On the smaller size
          scale we've seen setups where a team of half-a-dozen would
          support half-a-dozen services.</p>

<p>尽管“微服务”已经成为这种架构风格的一个流行名称，但它的名称确实导致了对服务大小的关注，以及对什么是“微”的争论。
    在我们与微服务实践者的对话中，我们看到服务的大小范围很广。
    据报道的最大规模遵循亚马逊的<a href="../bliki/TwoPizzaTeam.html">两比萨团队</a>（即整个团队可以用两个比萨饼喂饱），
    意味着不超过十几个人。
    在较小的规模上，我们看到了半打人组成的团队支持半打服务的设置。
</p>

<p>This leads to the question of whether there are
          sufficiently large differences within this size range that
          the service-per-dozen-people and service-per-person sizes
          shouldn't be lumped under one microservices label. At the
          moment we think it's better to group them together, but
          it's certainly possible that we'll change our mind as we
          explore this style further.</p>

<p>这引出了一个问题，即在这个规模范围内是否存在着足够大的差异，
    以至于每十人一个服务和每人一个服务的大小不应该被归在同一微服务标签下。
    目前我们认为将它们归为一类更好，
    但随着我们进一步探索这种风格，我们的想法可能会改变。
</p>
</aside>

<p>One company organised in this way is <a href="http://www.comparethemarket.com/">www.comparethemarket.com</a>.
        Cross functional teams are responsible for building and operating
        each product and each product is split out into a number of
        individual services communicating via a message bus.</p>

<p>这种方式组织的一家公司是<a href="http://www.comparethemarket.com/">www.comparethemarket.com</a>。
    跨职能团队负责构建和运营每个产品，
    每个产品都分割成多个独立的服务，
    这些服务通过消息总线进行通信。
</p>

<p>Large monolithic applications can always be modularized
        around business capabilities too, although that's not the
        common case. Certainly we would urge a large team building a
        monolithic application to divide itself along business lines.
        The main issue we have seen here, is that they tend to be
        organised around <i>too many</i> contexts. If the monolith
        spans many of these modular boundaries it can be difficult for individual
        members of a team to fit them into their short-term
        memory. Additionally we see that the modular
        lines require a great deal of discipline to enforce. The
        necessarily more explicit separation required by service
        components makes it easier to keep the team boundaries clear.</p>
    
<p>大型单体应用程序当然也可以围绕业务能力进行模块化，尽管这不是常见的情况。
    我们肯定会敦促一个大型团队在构建单体应用程序时按照业务线进行划分。
    我们在这里看到的主要问题是，它们往往围绕<i>太多</i>的上下文组织。
    如果单体跨越许多这些模块化边界，
    单个团队成员可能难以将它们纳入短期记忆。
    此外，我们还看到，模块化线条需要大量的纪律来执行。
    服务组件所需的更明确的分离使得保持团队边界清晰变得更加容易。
</p>
</section>

<section id="ProductsNotProjects">
<h3>Products not Projects</h3>

<p>Most application development efforts that we see use a
        project model: where the aim is to deliver some piece of
        software which is then considered to be completed. On
        completion the software is handed over to a
        maintenance organization and the project team that built it is
        disbanded.</p>

<p>我们看到的大多数应用程序开发工作都使用项目模型：目标是交付一些软件，然后认为这些软件已经完成。完成后，软件被移交给维护组织，构建它的项目团队被解散。
</p>

<p>Microservice proponents tend to avoid this model,
        preferring instead the notion that a team should own a product
        over its full lifetime. A common inspiration for this is
        Amazon's notion of <a href="https://queue.acm.org/detail.cfm?id=1142065">"you build, you
        run it"</a> where a development team takes full responsibility
        for the software in production. This brings developers into
        day-to-day contact with how their software behaves in
        production and increases contact with their users, as they
        have to take on at least some of the support burden.</p>

<p>微服务倡导者倾向于避免这种模型，
    而更倾向于认为一个团队应该在其整个生命周期内拥有一个产品。
    这种观点的一个常见灵感来源是亚马逊的<a href="https://queue.acm.org/detail.cfm?id=1142065">“你构建，你运行”</a>理念，
    其中开发团队对生产中的软件承担全部责任。
    这使开发人员能够与他们的软件在生产中的表现保持日常接触，
    并增加了与用户的接触，因为他们必须承担至少一部分支持负担。
</p>

<p>The product mentality, ties in with the linkage to business
        capabilities. Rather than looking at the software as a set of
        functionality to be completed, there is an on-going
        relationship where the question is how can software assist its
        users to enhance the business capability.</p>

<p>产品思维与业务能力的联系紧密相连。
    与其将软件视为一套要完成的功能，
    不如将其视为一种持续的关系，
    问题是软件如何帮助其用户增强业务能力。
</p>

<p>笔记: 问题是 一个软件产品的收入可以维持团队, 
    如果需要不断开发新产品才能维持，
    那么开发接触上一个产品的客户是否会降低这个产品的发布效率</p>

<p>There's no reason why this same approach can't be taken
        with monolithic applications, but the smaller granularity of
        services can make it easier to create the personal
        relationships between service developers and their users.</p>

<p>这种相同的方法也可以应用于单体应用程序，
    但服务的小粒度可以使
    服务开发人员与其用户之间， 创建个人关系更加容易。
</p>

</section>

<section id="SmartEndpointsAndDumbPipes">
<h3>Smart endpoints and dumb pipes</h3>

<p>When building communication structures between different
          processes, we've seen many products and approaches that stress
          putting significant smarts into the communication mechanism
          itself. A good example of this is the Enterprise Service Bus
          (ESB), where ESB products often include sophisticated
          facilities for message routing, choreography, transformation,
          and applying business rules.</p>


<p>在构建不同进程之间的通信结构时，我们看到了许多产品和方法，
    这些产品和方法强调将显著的智能放入通信机制本身。
    一个好的例子是企业服务总线（ESB），
    其中ESB产品通常包括复杂的消息路由、编排、转换和应用业务规则的功能。
</p>

<aside class="sidebar" id="MicroservicesAndSoa">
<h3>Microservices and SOA</h3>

<p>When we've talked about microservices a common question is
            whether this is just Service Oriented Architecture (SOA) that we
            saw a decade ago. There is merit to this point, because the
            microservice style is very similar to what some advocates of SOA
            have been in favor of. The problem, however, is that SOA means <a href="https://martinfowler.com/bliki/ServiceOrientedAmbiguity.html">too
            many different things</a>, and that most of the time that we come
            across something called "SOA" it's significantly different to the
            style we're describing here, usually due to a focus on ESBs used
            to integrate monolithic applications.</p>

<p>当我们谈论微服务时，一个常见的问题是这是否只是十年前我们见过的面向服务架构（SOA）。
    这个观点有一定的道理，因为微服务风格与一些SOA倡导者所推崇的风格非常相似。
        然而，问题在于SOA意味着<a href="https://martinfowler.com/bliki/ServiceOrientedAmbiguity.html">太多不同的事情</a>，
        而我们通常遇到的被称为“SOA”的东西与这里描述的风格大不相同，
        这通常是由于对使用ESB（企业服务总线）来集成单体应用程序的关注。
</p>

<p>In particular we have seen so many botched implementations of
            service orientation - from the tendency to hide complexity away
            in ESB's <span class="foot-ref"><a href="#footnote-esb">[5]</a></span>, to failed multi-year initiatives
            that cost millions and deliver no value, to centralised
            governance models that actively inhibit change, that it is
            sometimes difficult to see past these problems.</p>

<p>特别是我们看到了许多服务导向的糟糕实现 —— 从倾向于在ESB（企业服务总线）中隐藏复杂性，
    到耗时多年、花费数百万美元但毫无价值的失败举措，
    再到中央集权治理模式实际上抑制变化，
    这些问题有时很难克服。
</p>

<p>Certainly, many of the techniques in use in the microservice
            community have grown from the experiences of developers
            integrating services in large organisations. The <a href="https://martinfowler.com/bliki/TolerantReader.html">Tolerant Reader</a> pattern is an example of this. Efforts
            to use the web have contributed, using simple protocols is
            another approach derived from these experiences - a reaction
            away from central standards that have reached a complexity that
            is, <a href="http://wiki.apache.org/ws/WebServiceSpecifications">frankly,
            breathtaking</a>. (Any time you need an ontology to manage your
            ontologies you know you are in deep trouble.)</p>


<p>当然，微服务社区中使用的许多技术都是从大型组织中开发人员集成服务的经验中成长起来的。
    <a href="https://martinfowler.com/bliki/TolerantReader.html">宽容读者模式</a>就是这样一个例子。
    尝试使用网络也做出了贡献，
    使用简单协议是另一种从这些经验中衍生出来的方法 —— 这是对已经达到<a href="http://wiki.apache.org/ws/WebServiceSpecifications">令人叹为观止</a>的
    复杂性的中央标准的一种反应。
    （每次你需要一个本体来管理你的本体时，你都知道你已经陷入了大麻烦。）
</p>

<p>This common manifestation of SOA has led some microservice
            advocates to reject the SOA label entirely, although others
            consider microservices to be one form of SOA <span class="foot-ref"><a href="#footnote-fine-grained">[6]</a></span>, perhaps <i>service orientation done
            right</i>. Either way, the fact that SOA means such different
            things means it's valuable to have a term that more crisply
            defines this architectural style.</p>

<p>这种SOA的常见表现导致一些微服务倡导者完全拒绝SOA标签，
    尽管其他人认为微服务是SOA的一种形式，
    可能是<i>正确实现的服务导向</i>。
    不管怎样，SOA意味着
    存在不同的事情意味着
    有一个术语来更清晰地定义这种架构风格是有价值的。
</p>
</aside>

<p>The microservice community favours an alternative approach:
          <i>smart endpoints and dumb pipes</i>. Applications
          built from microservices aim to be as decoupled and as
          cohesive as possible - they own their own domain logic and act
          more as filters in the classical Unix sense - receiving a
          request, applying logic as appropriate and producing a
          response. These are choreographed using simple RESTish protocols rather
          than complex protocols such as WS-Choreography or BPEL or
          orchestration by a central tool.</p>

<p>微服务社区更喜欢另一种方法：<i>智能端点和哑管道</i>。
    由微服务构建的应用程序旨在尽可能地解耦和凝聚 —— 它们拥有自己的领域逻辑，
    并在经典Unix意义上更多地充当过滤器——接收请求，
    应用适当的逻辑并产生响应。
    这些使用简单的RESTish协议进行编排，
    而不是使用像WS-Choreography、BPEL或通过中心工具编排的复杂协议。
</p>

<p>The two protocols used most commonly are HTTP
          request-response with resource API's and lightweight
          messaging<span class="foot-ref"><a href="#footnote-protobufs">[7]</a></span>. The best expression of
          the first is</p>

<p>两种最常用的协议是HTTP请求-响应
    与资源API和轻量级消息传递[7]。
    第一种协议的最佳表达是
</p>

<blockquote>
<p>Be of the web, not behind the web </p>
<p>成为网络的一部分，而不是网络之后。</p>

<p class="quote-attribution">-- <a href="https://www.amazon.com/gp/product/0596805829/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0596805829&amp;linkCode=as2&amp;tag=martinfowlerc-20">Ian Robinson</a></p>
</blockquote>

<p>Microservice teams use the principles and
          protocols that the world wide web (and to a large extent,
          Unix) is built on. Often used resources can be cached with very
          little effort on the part of developers or operations
          folk. </p>
          
<p>微服务团队使用的是全世界网络（在很大程度上，还有Unix）所建立的原则和协议。
    通常使用的资源可以很容易地被开发人员或运维人员缓存。
</p>

<p>笔记: 这里的 cached 好像有掌握的意思</p>

<p>The second approach in common use is messaging over a
          lightweight message bus. The infrastructure chosen is
          typically dumb (dumb as in acts as a message router only) -
          simple implementations such as RabbitMQ or ZeroMQ don't do
          much more than provide a reliable asynchronous fabric - the
          smarts still live in the end points that are producing and
          consuming messages; in the services.</p>

<p>第二种常用的方法是通过轻量级消息总线进行消息传递。
    所选择的基础设施通常是哑的（哑即仅作为消息路由器）- 简单的实现，如RabbitMQ或ZeroMQ，
    除了提供可靠的无缝异步结构外，不做更多的事情；
    智能仍然存在于生产和服务消费消息的端点中。
</p>

<p>In a monolith, the components are executing in-process and
          communication between them is via either method invocation or
          function call. The biggest issue in changing a monolith into
          microservices lies in changing the communication pattern. A
          naive conversion from in-memory method calls to RPC leads to
          chatty communications which don't perform well. Instead you
          need to replace the fine-grained communication with a coarser
          -grained approach.</p>

<p>在单体中，组件在进程中执行，它们之间的通信是通过方法调用或函数调用来实现的。
    将单体转换为微服务最大的问题在于改变通信模式。
    从内存中的方法调用直接转换到RPC会导致过多的通信，这些通信表现不佳。
    相反，你需要用更粗粒度的方法替换细粒度的通信。
</p>

</section>

<section id="DecentralizedGovernance">
<h3>Decentralized Governance</h3>

<p>One of the consequences of centralised governance is the
        tendency to standardise on single technology
        platforms. Experience shows that this approach is constricting
        - not every problem is a nail and not every solution a
        hammer. We prefer using the right tool for the job and
        while monolithic applications can take advantage of different
        languages to a certain extent, it isn't that common.</p>

<p>集中治理的一个后果是倾向于在单一技术平台上进行标准化。
    经验表明，这种方法是限制性的 —— 并非每个问题都是钉子，并非每个解决方案都是锤子。
    我们更喜欢使用正确的工具来完成工作，
    尽管单体应用程序可以在一定程度上使用不同的语言，但这并不常见。
</p>

<p>Splitting the monolith's components out into services we
        have a choice when building each of them. You want to use
        Node.js to standup a simple reports page? Go for it. C++ for a
        particularly gnarly near-real-time component? Fine. You want
        to swap in a different flavour of database that better suits
        the read behaviour of one component? We have the technology to
        rebuild him.</p>

<p>将单体的组件拆分为服务后，在构建每个服务时我们都有选择。
    你想使用Node.js来建立一个简单的报告页面？没问题。
    想要用C++来构建一个特别复杂的准实时组件？也行。
    你想更换一个不同类型的数据库，它更适合某个组件的读取行为？
    我们有技术来重建它。
</p>

<p>Of course, just because you <i>can</i> do something,
        doesn't mean you <i>should</i> - but partitioning your system
        in this way means you have the option.</p>

<p>当然，只因为你<i>可以</i>做某件事，
    并不意味着你<i>应该</i>做 —— 但以这种方式划分你的系统意味着你有这个选项。
</p>

<p>Teams building microservices prefer a different approach to
        standards too. Rather than use a set of defined standards
        written down somewhere on paper they prefer the idea of
        producing useful tools that other developers can use to solve
        similar problems to the ones they are facing. These tools are
        usually harvested from implementations and shared with a wider
        group, sometimes, but not exclusively using an internal open
        source model. Now that git and github have become the de facto
        version control system of choice, open source practices are
        becoming more and more common in-house .</p>

<p>构建微服务的团队也喜欢不同的标准化方法。
    他们不倾向于使用一组定义好的标准，这些标准在纸上写下来。
    他们更喜欢产生有用工具的想法，
    其他开发者可以使用这些工具来解决他们面临的一些类似问题。
    这些工具通常是从实现中提取出来的，并与更广泛的群体共享，
    有时，但并不完全是通过内部开源模型来共享。
    由于git和github已经成为事实上的版本控制系统首选，开源实践变得越来越常见。
</p>

<p>Netflix is a good example of an organisation that follows
        this philosophy. Sharing useful and, above all, battle-tested
        code as libraries encourages other developers to solve similar
        problems in similar ways yet leaves the door open to picking a
        different approach if required. Shared libraries tend to be
        focused on common problems of data storage, inter-process
        communication and as we discuss further below, infrastructure
        automation.</p>

<p>Netflix是一个遵循这种哲学的组织的良好例子。
    共享有用且最重要的是经过实战测试的代码作为库，
    鼓励其他开发者以类似的方式解决类似的问题，
    但同时也为在必要时选择不同的方法留出了空间。
    共享库往往关注数据存储、进程间通信
    以及我们下面将进一步讨论的基础设施自动化等常见问题。
</p>

<p>For the microservice community, overheads are particularly
        unattractive. That isn't to say that the community doesn't
        value service contracts. Quite the opposite, since there tend
        to be many more of them. It's just that they are looking at
        different ways of managing those contracts. Patterns like
        <a href="https://martinfowler.com/bliki/TolerantReader.html">Tolerant Reader</a> and <a href="https://martinfowler.com/articles/consumerDrivenContracts.html">Consumer-Driven
        Contracts</a> are often applied to microservices. These aid
        service contracts in evolving independently. Executing
        consumer driven contracts as part of your build increases
        confidence and provides fast feedback on whether your services
        are functioning. Indeed we know of a team in Australia who
        drive the build of new services with consumer driven
        contracts. They use simple tools that allow them to define the
        contract for a service. This becomes part of the automated
        build before code for the new service is even written. The
        service is then built out only to the point where it satisfies
        the contract - an elegant approach to avoid the
        'YAGNI'<span class="foot-ref"><a href="#footnote-YAGNI">[8]</a></span> dilemma when building new
        software. These techniques and the tooling growing up around
        them, limit the need for central contract management by
        decreasing the temporal coupling between services. </p>

<p>对于微服务社区来说，开销尤其不受欢迎。
    这并不是说社区不重视服务合同。
    正相反，由于服务合同的数量通常更多。
    只是他们在寻找管理这些合同的不同方式。
    <a href="https://martinfowler.com/bliki/TolerantReader.html">宽容读者</a>
    和<a href="https://martinfowler.com/articles/consumerDrivenContracts.html">消费者驱动的合同</a>
    等模式经常应用于微服务。
    这些有助于独立演进服务合同。
    在构建过程中执行消费者驱动的合同可以增加信心，
    并提供快速反馈，了解你的服务是否正常工作。
    实际上，我们知道一家澳大利亚的团队使用消费者驱动的合同来驱动新服务的构建。
    他们使用简单的工具来定义一个服务的合同。
    这成为自动构建的一部分，甚至在为新服务编写代码之前。
    然后，该服务仅构建到满足合同的程度 —— 这是一种优雅的方法，
    避免了在构建新软件时出现“不需要”（YAGNI）的困境。
    这些技术和围绕它们的工具减少了服务之间的时间耦合，
    从而限制了对中心合同管理的需要。
</p>

<aside class="sidebar" id="ManyLanguagesManyOptions">
<h3>Many languages, many options</h3>

<p>The growth of JVM as a platform is just the latest
          example of
          mixing languages within a common platform. It's been common
          practice to shell-out to a higher level language to take advantage
          of higher level abstractions for decades. As is dropping down to
          the metal and writing performance sensitive code in a lower level
          one. However, many monoliths don't need this level of performance
          optimisation nor are DSL's and higher level abstractions that
          common (to our dismay). Instead monoliths are usually single
          language and the tendency is to limit the number of technologies
          in use <span class="foot-ref"><a href="#footnote-many-languages">[9]</a></span>.</p>
</aside>


<p>JVM作为一个平台的增长是在共同平台上混合语言的最新例子。
    几十年来，人们一直在使用更高层次的语言来利用更高层次的抽象。
    就像下到低级语言中编写性能敏感的代码一样。
    然而，许多单体并不需要这种性能优化级别的，DSL和更高层次的抽象也不常见（让我们感到遗憾）。
    相反，单体通常是单语言的，趋势是限制使用的技术数量<span class="foot-ref"><a href="#footnote-many-languages">[9]</a></span>。
</p>
</aside>

<p>Perhaps the apogee of decentralised governance is the build
        it / run it ethos popularised by Amazon. Teams are responsible
        for all aspects of the software they build including operating
        the software 24/7. Devolution of this level of responsibility
        is definitely not the norm but we do see more and more
        companies pushing responsibility to the development
        teams. Netflix is another organisation that has adopted this
        ethos<span class="foot-ref"><a href="#footnote-netflix-flowcon">[10]</a></span>. Being woken up at 3am
        every night by your pager is certainly a powerful incentive to
        focus on quality when writing your code. These ideas are about
        as far away from the traditional centralized governance model
        as it is possible to be.</p>

<p>去中心化治理的顶峰可能是亚马逊推广的“构建它/运行它”的理念。
    团队负责他们所构建软件的所有方面，包括全天候运行软件。
    将这种级别的责任下放绝对不是常态，
    但我们确实看到越来越多的公司推动责任到开发团队。
    Netflix是另一个采用这种理念的组织<span class="foot-ref"><a href="#footnote-netflix-flowcon">[10]</a></span>。
    每晚被你的呼机叫醒确实是一个强有力的激励，让你在编写代码时专注于质量。
    这些理念与传统的集中治理模型相去甚远。
</p>
</section>

<section id="DecentralizedDataManagement">
<h3>Decentralized Data Management</h3>

<p>Decentralization of data management presents in a number of
        different ways. At the most abstract level, it means that the
        conceptual model of the world will differ between systems.
        This is a common issue when integrating across a large
        enterprise, the sales view of a customer will differ from the
        support view. Some things that are called customers in the
        sales view may not appear at all in the support view. Those
        that do may have different attributes and (worse) common
        attributes with subtly different semantics.</p>

<p>数据管理的去中心化以多种不同的方式呈现。
    在最抽象的层面上，这意味着世界观的概念模型将在不同的系统之间有所不同。
    这是在大规模企业中集成的常见问题，销售视图中的客户与支持视图中的客户会有所不同。
    在销售视图中被称为客户的一些事物在支持视图中可能根本不会出现。
    那些出现的事物可能有不同的属性，而且（更糟糕的是）常见的属性带有微妙的语义差异。
</p>

<aside class="sidebar" id="Battle-testedStandardsAndEnforcedStandards">
<h3>Battle-tested standards and enforced standards</h3>

<p>It's a bit of a dichotomy that microservice teams tend to
          eschew the kind of rigid enforced standards laid down by
          enterprise architecture groups but will happily use and even
          evangelise the use of open standards such as HTTP, ATOM and
          other microformats.</p>

<p>微服务团队倾向于避免企业架构组制定的那种严格强制执行的标准，
    但会欣然使用甚至宣传使用开放标准，
    如HTTP、ATOM和其他微格式，这有点矛盾。
</p>

<p>The key difference is how the standards are developed and
          how they are enforced. Standards managed by groups such as
          the IETF only <i>become</i> standards when there are several
          live implementations of them in the wider world and which
          often grow from successful open-source projects.</p>

<p>关键的区别在于标准的开发方式和执行方式。
    像IETF这样的组织管理的标准只有在世界上有几种实时的实现，
    并且这些实现往往是从成功的开源项目中成长起来的，才能<i>成为</i>标准。
</p>

<p>These standards are a world apart from many in a
          corporate world, which are often developed by groups that
          have little recent programming experience or overly influenced
          by vendors.</p>

<p>这些标准与许多企业世界中的标准大相径庭，
    后者往往是由那些近期缺乏编程经验或过于受供应商影响的团队开发的。
</p>
</aside>

<p>This issue is common between applications, but can also
        occur <i>within</i> applications, particular when that
        application is divided into separate components. A useful way
        of thinking about this is the Domain-Driven Design notion of
        <a href="https://martinfowler.com/bliki/BoundedContext.html">Bounded Context</a>. DDD divides a complex
        domain up into multiple bounded contexts and maps out the
        relationships between them. This process is useful
        for both monolithic and microservice architectures, but there
        is a natural correlation between service and context
        boundaries that helps clarify, and as we describe in the
        section on business capabilities, reinforce the
        separations.</p>

<p>这个问题在应用程序之间很常见，但也可以发生在<i>应用程序内部</i>，
    特别是当应用程序被划分为独立的组件时。
    一个有用的思考方式是域驱动设计（DDD）中的<a href="../bliki/BoundedContext.html">边界上下文</a>概念。
    DDD将复杂领域划分为多个边界上下文，并绘制出它们之间的关系。
    这个过程对于单体和微服务架构都有用，
    但服务和服务边界与上下文边界之间存在自然的相关性，
    这有助于澄清，如我们在业务能力部分所述，加强分离。
</p>

<p>As well as decentralizing decisions about conceptual
        models, microservices also decentralize data storage
        decisions. While monolithic applications prefer a single logical
        database for persistant data, enterprises often prefer a
        single database across a range of applications - many of these
        decisions driven through vendor's commercial models around
        licensing.  Microservices prefer letting each service manage
        its own database, either different instances of the same
        database technology, or entirely different database systems -
        an approach called <a href="https://martinfowler.com/bliki/PolyglotPersistence.html">Polyglot Persistence</a>. You
        can use polyglot persistence in a monolith, but it appears
        more frequently with microservices.</p>

<p>除了去中心化关于概念模型的决策外，
    微服务还去中心化数据存储决策。
    虽然单体应用程序倾向于使用单个逻辑数据库来持久化数据，
    但企业通常更喜欢在一系列应用程序之间使用单个数据库 —— 许多这些决策都是由与许可相关的供应商的商业模型驱动的。
    微服务倾向于让每个服务管理自己的数据库，
    无论是相同数据库技术的不同实例，
    还是完全不同的数据库系统——这种方法称为<a href="../bliki/PolyglotPersistence.html">多语言持久性</a>。
    你可以在单体中使用多语言持久性，但它在微服务中出现得更频繁。
</p>

<div class="figure " id="microservices_images_decentralised-data.png"><img src="microservices_files/decentralised-data.png">
<p class="photoCaption"></p>
</div>

<div class="clear"></div>

<p>Decentralizing responsibility for data across microservices
        has implications for managing updates. The common
        approach to dealing with updates has been to use transactions
        to guarantee consistency when updating multiple resources.
        This approach is often used within monoliths.</p>

<p>在微服务中将数据管理责任去中心化对处理更新有影响。
    处理更新的常见方法是使用事务来保证在更新多个资源时的一致性。
    这种方法通常在单体中使用。
</p>

<p>Using transactions like this helps with consistency, but
        imposes significant temporal coupling, which is problematic
        across multiple services. Distributed transactions are
        notoriously difficult to implement and as a consequence
        microservice architectures <a href="http://www.eaipatterns.com/ramblings/18_starbucks.html">emphasize
        transactionless coordination between services</a>, with
        explicit recognition that consistency may only be eventual
        consistency and problems are dealt with by compensating
        operations.</p>

<p>使用这样的事务有助于保持一致性，
    但施加了显著的时间耦合，这在多个服务之间是有问题的。
    分布式事务很难实现，
    因此微服务架构强调服务之间的无事务协调，
    明确认识到一致性可能只是最终一致性，
    并且通过补偿操作来解决问题。
</p>

<p>Choosing to manage inconsistencies in this way is a new
  challenge for many development teams, but it is one that often
  matches business practice. Often businesses handle a degree of
  inconsistency in order to respond quickly to demand, while
  having some kind of reversal process to deal with
  mistakes. The trade-off is worth it as long as the cost of
  fixing mistakes is less than the cost of lost business under
  greater consistency.</p>


<p>选择以这种方式管理不一致性对于许多开发团队来说是一个新的挑战，
    但通常这与业务实践相匹配。
    通常，业务为了快速响应需求，会处理一定程度的不一致性，
    同时具有某种纠错流程来处理错误。
    只要修复错误的成本低于在更大的一致性下失去业务的成本，
    这种权衡就是值得的。
</p>
</section>

<section id="InfrastructureAutomation">
<h3>Infrastructure Automation</h3>

<p>Infrastructure automation techniques have evolved
        enormously over the last few years - the evolution of the
        cloud and AWS in particular has reduced the operational
        complexity of building, deploying and operating
        microservices.</p>

<p>在过去几年中，基础设施自动化技术已经发展巨大 —— 特别是云计算和AWS的发展
    已经降低了构建、部署和运营微服务的操作复杂性。
</p>

<p>Many of the products or systems being build with
        microservices are being built by teams with extensive
        experience of <a href="https://martinfowler.com/bliki/ContinuousDelivery.html">Continuous Delivery</a> and it's
        precursor, <a href="https://martinfowler.com/articles/continuousIntegration.html">Continuous
        Integration</a>. Teams building software this way make
  extensive use of infrastructure automation techniques. This is
  illustrated in the build pipeline shown below.</p>

<p>许多使用微服务构建的产品或系统是由具有<a href="../bliki/ContinuousDelivery.html">持续交付</a>和
    其前身<a href="../articles/continuousIntegration.html">持续集成</a>丰富经验的团队构建的。
    采用这种方式构建软件的团队大量使用基础设施自动化技术。
    这在下面所示的构建流水线中得到了说明。
</p>


<div class="figure " id="microservices_images_basic-pipeline.png"><img src="microservices_files/basic-pipeline.png">
<p class="photoCaption">Figure 5: basic
        build pipeline</p>
</div>

<div class="clear"></div>

<p>Since this isn't an article on Continuous Delivery we will
        call attention to just a couple of key features here. We want
        as much confidence as possible that our software is working,
        so we run lots of <b>automated tests</b>. Promotion of working
        software 'up' the pipeline means we <b>automate deployment</b>
        to each new environment.</p>

<p>由于这不是一篇关于持续交付的文章，我们在这里将关注几个关键特性。
    我们希望尽可能地确保我们的软件能够正常工作，
    因此我们会运行大量的<b>自动化测试</b>。
    将工作软件在流水线上“向上”推广
    意味着我们会<b>自动化部署</b>到每个新的环境。
</p>

<aside class="sidebar" id="MakeItEasyToDoTheRightThing">
<h3>Make it easy to do the right thing</h3>

<p>One side effect we have found of increased automation as
          a consequence of continuous delivery and deployment is the
          creation of useful tools to help developers and operations
          folk. Tooling for creating artefacts, managing codebases,
          standing up simple services or for adding standard
          monitoring and logging are pretty common now. The best
          example on the web is probably <a href="http://netflix.github.io/">Netflix's set of open
          source tools</a>, but there are others including <a href="http://dropwizard.codahale.com/">Dropwizard</a> which
          we have used extensively.</p>

<p>我们发现，由于持续交付和部署导致的自动化增加，
    一个副作用是为开发人员和运维人员创造了有用的工具。
    用于创建工件、管理代码库、搭建简单服务或添加标准监控和日志的工具现在相当普遍。
    网站上最好的例子可能是<a href="http://netflix.github.io/">Netflix的开源工具集</a>，
    但还有其他一些，包括我们广泛使用的<a href="http://dropwizard.codahale.com/">Dropwizard</a>。
</p>

</aside>

<p>A monolithic application will be built, tested and pushed
        through these environments quite happlily. It turns out that
        once you have invested in automating the path to production
        for a monolith, then deploying <i>more</i> applications
        doesn't seem so scary any more. Remember, one of the aims of
        CD is to make deployment boring, so whether its one or three
        applications, as long as its still boring it doesn't
        matter<span class="foot-ref"><a href="#footnote-trickycd">[11]</a></span>. </p>

<p>一个单体应用程序将能够非常顺利地通过这些环境进行构建、测试和推送。
    结果证明，一旦你为单体应用程序投入自动化生产路径，
    那么部署<i>更多</i>应用程序似乎不再那么可怕。
    记住，持续交付（CD）的一个目标是使部署变得无聊，
    所以无论是部署一个还是三个应用程序，只要它仍然无聊，那就无关紧要。
    <span class="foot-ref"><a href="#footnote-trickycd">[11]</a></span>
</p>

<p>Another area where we see teams using extensive
        infrastructure automation is when managing microservices in
        production. In contrast to our assertion above that as long as
        deployment is boring there isn't that much difference between
        monoliths and microservices, the operational landscape for
        each can be strikingly different.</p>

<p>在我们观察到的另一个领域，
    团队在使用基础设施自动化方面极为广泛，那就是在生产环境中管理微服务。
    与我们在上面提出的观点相反，只要部署过程无聊，
    单体和微服务之间并没有太大差异，
    每个服务的运营环境可能会有显著的不同。
</p>

<div class="figure " id="microservices_images_micro-deployment.png"><img src="microservices_files/micro-deployment.png">
<p class="photoCaption">Figure 6: Module
        deployment often differs</p>
</div>

<div class="clear"></div>
</section>

<section id="DesignForFailure">
<h3>Design for failure</h3>

<p>A consequence of using services as components, is that
        applications need to be designed so that they can tolerate the
        failure of services. Any service call could fail due to
        unavailability of the supplier, the client has to respond to
        this as gracefully as possible. This is a disadvantage
        compared to a monolithic design as it introduces additional
        complexity to handle it. The consequence is that microservice
        teams constantly reflect on how service failures affect the
        user experience. Netflix's <a href="https://github.com/Netflix/SimianArmy">Simian Army</a>
        induces failures of services and even datacenters during the
        working day to test both the application's resilience and
        monitoring.</p>

<p>将服务作为组件使用的一个后果是，应用程序需要设计成能够容忍服务失败。
    由于服务供应商的不可用，任何服务调用都可能失败，客户端必须尽可能优雅地响应这种情况。
    与单体设计相比，这是一个劣势，因为它引入了处理额外的复杂性。
    后果是微服务团队不断反思服务失败如何影响用户体验。
    Netflix的<a href="https://github.com/Netflix/SimianArmy">Simian Army</a>在工作时间内引入服务甚至数据中心故障，
    以测试应用程序的弹性和监控。
</p>

<aside class="sidebar" id="TheCircuitBreakerAndProductionReadyCode">
<h3>The circuit breaker and production ready code</h3>

<p><a href="https://martinfowler.com/bliki/CircuitBreaker.html">Circuit Breaker</a> appears in <a href="https://www.amazon.com/gp/product/B00A32NXZO/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B00A32NXZO&amp;linkCode=as2&amp;tag=martinfowlerc-20">Release It!</a> alongside other
    patterns such as Bulkhead and Timeout. Implemented together,
    these patterns are crucially important when building
    communicating applications. This <a href="http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html">Netflix
    blog entry</a> does a great job of explaining their
    application of them.</p>

<p><a href="https://martinfowler.com/bliki/CircuitBreaker.html">Circuit Breaker</a> appears in <a href="https://www.amazon.com/gp/product/B00A32NXZO/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B00A32NXZO&amp;linkCode=as2&amp;tag=martinfowlerc-20">Release It!</a> alongside other
    patterns such as Bulkhead and Timeout. Implemented together,
    these patterns are crucially important when building
    communicating applications. This <a href="http://techblog.netflix.com/2012/02/fault-tolerance-in-high-volume.html">Netflix
    blog entry</a> does a great job of explaining their
    application of them.</p>
    
</aside>

<p>This kind of automated testing in production would be
        enough to give most operation groups the kind of shivers
        usually preceding a week off work. This isn't to say that
        monolithic architectural styles aren't capable of
        sophisticated monitoring setups - it's just less common in our
        experience.</p>

<p>Since services can fail at any time, it's important to be
        able to detect the failures quickly and, if possible,
        automatically restore service. Microservice applications put a
        lot of emphasis on real-time monitoring of the application,
        checking both architectural elements (how many requests per
        second is the database getting) and business relevant metrics
        (such as how many orders per minute are received). Semantic
        monitoring can provide an early warning system of something
        going wrong that triggers development teams to follow up and
        investigate.</p>

<p>This is particularly important to a microservices
        architecture because the microservice preference towards
        choreography and <a href="https://martinfowler.com/eaaDev/EventCollaboration.html">event collaboration</a>
        leads to emergent behavior. While many pundits praise the
        value of serendipitous emergence, the truth is that emergent
        behavior can sometimes be a bad thing. Monitoring is vital to
        spot bad emergent behavior quickly so it can be fixed.</p>

<aside class="sidebar" id="SynchronousCallsConsideredHarmful">
<h3>Synchronous calls considered harmful</h3>

<p>Any time you have a number of synchronous calls between services you will
    encounter the multiplicative effect of downtime. Simply,
    this is when the downtime of your system becomes the product
    of the downtimes of the individual components. You face a
    choice, making your calls asynchronous or managing
    the downtime. At www.guardian.co.uk they have implemented a
    simple rule on the new platform - one synchronous call per
    user request while at Netflix, their platform API redesign
    has built asynchronicity into the API fabric.</p>
</aside>

<p>Monoliths can be built to be as transparent as a
        microservice - in fact, they should be. The difference is that
        you absolutely need to know when services running in different
        processes are disconnected. With libraries within the same
        process this kind of transparency is less likely to be
        useful.</p>

<p>Microservice teams would expect to see sophisticated
        monitoring and logging setups for each individual
        service such as dashboards showing up/down status and a variety of
        operational and business relevant metrics. Details on circuit
        breaker status, current throughput and latency are other
        examples we often encounter in the wild.</p>
</section>

<section id="EvolutionaryDesign">
<h3>Evolutionary Design</h3>

<p>Microservice practitioners, usually have come from
        an evolutionary design background and see service
        decomposition as a further tool to enable application
        developers to control changes in their application without
        slowing down change. Change control doesn't necessarily mean
        change reduction - with the right attitudes and tools you can
        make frequent, fast, and well-controlled changes to
        software.</p>

<p>Whenever you try to break a software system into
        components, you're faced with the decision of how to divide up
        the pieces - what are the principles on which we decide to
        slice up our application? The key property of a component is
        the notion of independent replacement and
        upgradeability<span class="foot-ref"><a href="#footnote-RCA">[12]</a></span> - which implies we look for
        points where we can imagine rewriting a component without
        affecting its collaborators.  Indeed many microservice groups
        take this further by explicitly expecting many services to be
        scrapped rather than evolved in the longer term.</p>

<p>The Guardian website is a good example of an application
        that was designed and built as a monolith, but has been
        evolving in a microservice direction. The monolith still is
        the core of the website, but they prefer to add new features
        by building microservices that use the monolith's API. This
        approach is particularly handy for features that are
        inherently temporary, such as specialized pages to handle a
        sporting event. Such a part of the website can quickly be put
        together using rapid development languages, and removed once
        the event is over. We've seen similar approaches at a
        financial institution where new services are added for a
        market opportunity and discarded after a few months or even
        weeks.</p>

<p>This emphasis on replaceability is a special case of a more
        general principle of modular design, which is to drive
        modularity through the pattern of change <span class="foot-ref"><a href="#footnote-beck-rate-of-change">[13]</a></span>. You want to keep things that change
        at the same time in the same module. Parts of a system that
        change rarely should be in different services to those that
        are currently undergoing lots of churn. If you find yourself
        repeatedly changing two services together, that's a sign that
        they should be merged.</p>

<p>Putting components into services adds an opportunity for
        more granular release planning. With a monolith any changes
        require a full build and deployment of the entire
        application. With microservices, however, you only need to
        redeploy the service(s) you modified. This can simplify and
        speed up the release process. The downside is that you have to
        worry about changes to one service breaking its
        consumers. The traditional integration approach is to try to deal
        with this problem using versioning, but the preference in the
        microservice world is to <a href="https://martinfowler.com/articles/enterpriseREST.html#versioning">only
        use versioning as a last resort</a>. We can avoid a lot of
        versioning by designing services to be as tolerant as possible
        to changes in their suppliers.</p>
</section>
</section>

<section id="AreMicroservicesTheFuture">
<h2>Are Microservices the Future?</h2>

<p>Our main aim in writing this article is to explain the major
      ideas and principles of microservices. By taking the time to do
      this we clearly think that the microservices architectural style
      is an important idea - one worth serious consideration for
      enterprise applications. We have recently built several systems
      using the style and know of others who have used and favor this
      approach.</p>

<aside>
<div class="article-card">
<h3><a href="https://martinfowler.com/articles/microservice-trade-offs.html">Microservice Trade-Offs</a></h3>

<div class="card-body">
<p class="card-image"><img src="microservices_files/card.png"></p>

<p class="abstract">
    Many development teams have found the microservices architectural style to be
    a superior approach to a monolithic architecture. But other teams
    have found them to be a productivity-sapping burden. Like any
    architectural style, microservices bring costs and benefits. To
    make a sensible choice you have to understand these and apply them
    to your specific context.
  </p>

<div class="meta">
<p class="credits">by Martin Fowler</p>

<p class="date">1 Jul 2015</p>

<p class="more"><a href="https://martinfowler.com/articles/microservice-trade-offs.html">Read more…</a></p>

<p class="type article">article</p>

<p class="tags"> <span class="tag-link"><a href="https://martinfowler.com/tags/microservices.html">microservices</a></span> </p>
</div>
</div>
</div>
</aside>

<p>Those we know about who are in some way pioneering the
      architectural style include Amazon, Netflix, <a href="http://www.theguardian.com/">The Guardian</a>, the <a href="https://gds.blog.gov.uk/">UK Government Digital Service</a>, <a href="https://martinfowler.com/articles/realestate.com.au">realestate.com.au</a>, Forward and <a href="http://www.comparethemarket.com/">comparethemarket.com</a>. The
      conference circuit in 2013 was full of examples of companies
      that are moving to something that would class as microservices -
      including Travis CI. In addition there are plenty of
      organizations that have long been doing what we would class as
      microservices, but without ever using the name. (Often this is
      labelled as SOA - although, as we've said, SOA comes in many
      contradictory forms. <span class="foot-ref"><a href="#footnote-already">[14]</a></span>) </p>

<p>Despite these positive experiences, however, we aren't
      arguing that we are certain that microservices are the future
      direction for software architectures. While our experiences so
      far are positive compared to monolithic applications, we're
      conscious of the fact that not enough time has passed for us to
      make a full judgement.</p>

<p>Often the true consequences of your architectural decisions
      are only evident several years after you made them. We have seen
      projects where a good team, with a strong desire for
      modularity, has built a monolithic architecture that has
      decayed over the years. Many people believe that such decay is
      less likely with microservices, since the service boundaries are
      explicit and hard to patch around. Yet until we see enough
      systems with enough age, we can't truly assess how microservice
      architectures mature.</p>

<p>There are certainly reasons why one might expect
      microservices to mature poorly. In any effort at
      componentization, success depends on how well the software fits
      into components. It's hard to figure out exactly where the
      component boundaries should lie. Evolutionary design recognizes
      the difficulties of getting boundaries right and thus the
      importance of it being easy to refactor them. But when your
      components are services with remote communications, then
      refactoring is much harder than with in-process libraries.
      Moving code is difficult across service boundaries, any
      interface changes need to be coordinated between participants,
      layers of backwards compatibility need to be added, and testing
      is made more complicated.</p>

<div class="book-sidebar"><span class="img-link"><a href="https://www.amazon.com/gp/product/1491950358/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=1491950358&amp;linkCode=as2&amp;tag=martinfowlerc-20"><img class="cover" src="microservices_files/sam-book.jpg"></a></span>
<p>Our colleague Sam Newman spent most of 2014 working on a
        book that captures our experiences with building
        microservices. This should be your next step if you want a deeper
        dive into the topic.</p>
</div>

<p>Another issue is If the components do not compose cleanly, then
      all you are doing is shifting complexity from inside a component
      to the connections between components. Not just does this just
      move complexity around, it moves it to a place that's less
      explicit and harder to control. It's easy to think things are
      better when you are looking at the inside of a small, simple
      component, while missing messy connections between services.</p>

<p>Finally, there is the factor of team skill. New techniques
      tend to be adopted by more skillful teams. But a technique that
      is more effective for a more skillful team isn't necessarily
      going to work for less skillful teams. We've seen plenty of
      cases of less skillful teams building messy monolithic
      architectures, but it takes time to see what happens when this
      kind of mess occurs with microservices. A poor team will always
      create a poor system - it's very hard to tell if microservices
      reduce the mess in this case or make it worse.</p>

<p>One reasonable argument we've heard is that you shouldn't
      start with a microservices architecture. Instead
      <a href="https://martinfowler.com/bliki/MonolithFirst.html">begin with a monolith</a>,
      keep it modular, and split it into microservices once the
      monolith becomes a problem. (Although
      <a href="https://martinfowler.com/articles/dont-start-monolith.html">this advice isn't ideal</a>,
      since a good in-process interface is usually not a good service interface.)</p>

<p>So we write this with cautious optimism. So far, we've seen
      enough about the microservice style to feel that it can be
      <a href="https://martinfowler.com/microservices/">a worthwhile road to tread</a>.
      We can't say for sure where we'll end
      up, but one of the challenges of software development is that
      you can only make decisions based on the imperfect information
      that you currently have to hand.</p>
</section>

<hr class="bodySep">
</div>

<div class="appendix">
<div class="footnote-list">
<h2>Footnotes</h2>

<div class="footnote-list-item" id="footnote-etymology">
<p><span class="num">1: </span>
      The term "microservice" was discussed at a workshop of software
      architects near Venice in May, 2011 to describe what the
      participants saw as a common architectural style that many of
      them had been recently exploring. In May 2012, the same group decided on
      "microservices" as the most appropriate name. James presented some of these
      ideas as a case study in March 2012 at 33rd Degree in Krakow in
      <a href="http://2012.33degree.org/talk/show/67">Microservices
      - Java, the Unix Way</a> as did Fred George <a href="http://www.slideshare.net/fredgeorge/micro-service-architecure">about
      the same time</a>. Adrian Cockcroft at Netflix, describing this
      approach as "fine grained SOA" was pioneering the style at web
      scale as were many of the others mentioned in this article - Joe
      Walnes, Daniel Terhorst-North, Evan Botcher and
      Graham Tackley.
    </p>
</div>

<div class="footnote-list-item" id="footnote-monolith">
<p><span class="num">2: </span>
      The term monolith has been in use by the Unix community for some
      time. It appears in <a href="https://www.amazon.com/gp/product/B003U2T5BA/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=B003U2T5BA&amp;linkCode=as2&amp;tag=martinfowlerc-20">The Art of Unix
      Programming</a> to describe systems that get too big.
    </p>
</div>

<div class="footnote-list-item" id="footnote-service-object">
<p><span class="num">3: </span>
      Many object-oriented designers, including ourselves, use the
      term service object in the <a href="https://www.amazon.com/gp/product/0321125215/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321125215&amp;linkCode=as2&amp;tag=martinfowlerc-20">Domain-Driven
      Design</a> sense for an object that carries out a significant
      process that isn't tied to an entity. This is a different
      concept to how we're using "service" in this article. Sadly the
      term service has both meanings and we have to live with the
      polyseme.
    </p>
</div>

<div class="footnote-list-item" id="footnote-application">
<p><span class="num">4: </span>
      We consider <a href="https://martinfowler.com/bliki/ApplicationBoundary.html">an application to be a social
      construction</a> that binds together a code base, group of
      functionality, and body of funding.
    </p>
</div>

<div class="footnote-list-item" id="footnote-esb">
<p><span class="num">5: </span>
      We can't resist mentioning Jim Webber's statement that ESB
      stands for <a href="http://www.infoq.com/presentations/soa-without-esb">"Erroneous
      Spaghetti Box"</a>. </p>
</div>

<div class="footnote-list-item" id="footnote-fine-grained">
<p><span class="num">6: </span>
      Netflix makes the link explicit - until recently referring to
      their architectural style as fine-grained SOA.
    </p>
</div>

<div class="footnote-list-item" id="footnote-protobufs">
<p><span class="num">7: </span>
      At extremes of scale, organisations often move to binary
      protocols - <a href="https://code.google.com/p/protobuf/">protobufs</a> for
      example. Systems using these still exhibit the characteristic of
      smart endpoints, dumb pipes - and trade off <i>transparency</i>
      for scale. Most web properties and certainly the vast majority
      of enterprises don't need to make this tradeoff - transparency
      can be a big win.
    </p>
</div>

<div class="footnote-list-item" id="footnote-YAGNI">
<p><span class="num">8: </span>
      "YAGNI" or "You Aren't Going To Need It" is an <a href="http://c2.com/cgi/wiki?YouArentGonnaNeedIt">XP
      principle</a> and exhortation to not add features until you know
      you need them.
    </p>
</div>

<div class="footnote-list-item" id="footnote-many-languages">
<p><span class="num">9: </span>
      It's a little disengenuous of us to claim that monoliths are
      single language - in order to build systems on todays web, you
      probably need to know JavaScript and XHTML, CSS, your server
      side language of choice, SQL and an ORM dialect. Hardly single
      language, but you know what we mean.
    </p>
</div>

<div class="footnote-list-item" id="footnote-netflix-flowcon">
<p><span class="num">10: </span>
      Adrian Cockcroft specifically mentions "developer self-service"
      and "Developers run what they wrote"(sic) in <a href="http://www.slideshare.net/adrianco/flowcon-added-to-for-cmg-keynote-talk-on-how-speed-wins-and-how-netflix-is-doing-continuous-delivery">this
      excellent presentation</a> delivered at Flowcon in November,
      2013.
    </p>
</div>

<div class="footnote-list-item" id="footnote-trickycd">
<p><span class="num">11: </span>
      We are being a little disengenuous here. Obviously deploying
      more services, in more complex topologies is more difficult than
      deploying a single monolith. Fortunately, patterns reduce this
      complexity - investment in tooling is still a must though.
    </p>
</div>

<div class="footnote-list-item" id="footnote-RCA">
<p><span class="num">12: </span>
      In fact, Daniel Terhorst-North refers to this style as <i>Replaceable
      Component Architecture</i> rather than microservices. Since this
      seems to talk to a subset of the characteristics we prefer the
      latter.
    </p>
</div>

<div class="footnote-list-item" id="footnote-beck-rate-of-change">
<p><span class="num">13: </span>
      Kent Beck highlights this as one his design principles in
      <a href="https://www.amazon.com/gp/product/0321413091/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321413091&amp;linkCode=as2&amp;tag=martinfowlerc-20">Implementation Patterns</a>.
    </p>
</div>

<div class="footnote-list-item" id="footnote-already">
<p><span class="num">14: </span>
      And SOA is hardly the root of this history. I remember people saying
      "we've been doing this for years" when the SOA term appeared at
      the beginning of the century. One argument was that this style
      sees its roots as the way COBOL programs communicated via data
      files in the earliest days of enterprise computing. In another
      direction, one could argue that microservices are the same thing
      as the Erlang programming model, but applied to an enterprise
      application context.
    </p>
</div>
</div>

<section id="References">
<h2>References</h2>

<p>While this is not an exhaustive list, there are a number of sources
that practitioners have drawn inspiration from or which espouse a
similar philosophy to that described in this article.</p>

<p>Blogs and online articles</p>

<ul>
<li><a href="http://blogs.msdn.com/b/clemensv/">Clemens Vasters’ blog
on cloud at microsoft</a></li>

<li><a href="http://davidmorgantini.blogspot.com/2013/08/micro-services-introduction.htm">David
Morgantini’s introduction to the topic on his blog</a></li>

<li><a href="http://12factor.net/">12 factor apps from Heroku</a></li>

<li><a href="https://www.gov.uk/design-principles">UK Government
Digital Service design principles</a></li>

<li><a href="http://jimmynilsson.com/blog/">Jimmy Nilsson’s blog</a><a href="http://www.infoq.com/articles/CCC-Jimmy-Nilsson">and article
on infoq about Cloud Chunk Computing</a></li>

<li><a href="http://alistair.cockburn.us/Hexagonal+architecture">Alistair
Cockburn on Hexagonal architectures</a></li>
</ul>

<p>Books</p>

<ul>
<li><a href="https://www.amazon.com/gp/product/0978739213/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0978739213&amp;linkCode=as2&amp;tag=martinfowlerc-20">Release it</a></li>

<li><a href="https://www.amazon.com/gp/product/0596805829/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0596805829&amp;linkCode=as2&amp;tag=martinfowlerc-20">Rest in practice</a></li>

<li><a href="https://pages.apigee.com/web-api-design-ebook.html">Web
API Design (free ebook)</a>. Brian Mulloy, Apigee.</li>

<li><a href="https://www.amazon.com/gp/product/0321200683/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321200683&amp;linkCode=as2&amp;tag=martinfowlerc-20">Enterprise Integration
Patterns</a></li>

<li><a href="https://www.amazon.com/gp/product/0131429019/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0131429019&amp;linkCode=as2&amp;tag=martinfowlerc-20">Art of unix programming</a></li>

<li><a href="https://www.amazon.com/gp/product/0321503627/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321503627&amp;linkCode=as2&amp;tag=martinfowlerc-20">Growing Object Oriented Software, Guided
by Tests</a></li>

<li><a href="https://www.amazon.com/gp/product/0198293755/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0198293755&amp;linkCode=as2&amp;tag=martinfowlerc-20">The Modern Firm: Organizational Design for
Performance and Growth</a></li>

<li><a href="https://www.amazon.com/gp/product/0321601912/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321601912&amp;linkCode=as2&amp;tag=martinfowlerc-20">Continuous Delivery: Reliable Software
Releases through Build, Test, and Deployment Automation</a></li>

<li><a href="https://www.amazon.com/gp/product/0321125215/ref=as_li_tl?ie=UTF8&amp;camp=1789&amp;creative=9325&amp;creativeASIN=0321125215&amp;linkCode=as2&amp;tag=martinfowlerc-20">Domain-Driven Design: Tackling Complexity
in the Heart of Software</a></li>
</ul>

<p>Presentations</p>

<ul>
<li><a href="https://www.youtube.com/watch?v=qVyt3qQ_7TA">Architecture
without Architects</a>. Erik Doernenburg.</li>

<li><a href="http://www.infoq.com/presentations/soa-without-esb">Does
my bus look big in this?</a>. Jim Webber and Martin Fowler, QCon
2008</li>

<li><a href="http://www.infoq.com/presentations/webber-guerilla-soa">Guerilla
SOA</a>. Jim Webber, 2006</li>

<li><a href="http://vimeo.com/43659070">Patterns of Effective
Delivery</a>. Daniel Terhorst-North, 2011.</li>

<li><a href="http://www.slideshare.net/adrianco">Adrian Cockcroft's
slideshare channel</a>.</li>

<li><a href="http://vimeo.com/28608667">Hydras and Hypermedia</a>. Ian
Robinson, JavaZone 2010</li>

<li><a href="">Justice will take a million intricate
moves</a>. Leonard Richardson, Qcon 2008.</li>

<li><a href="http://vimeo.com/74452550">Java, the UNIX way</a>. James
Lewis, JavaZone 2012</li>

<li><a href="http://yow.eventer.com/yow-2012-1012/micro-services-architecture-by-fred-george-1286">Micro
services architecture</a>. Fred George, YOW! 2012</li>

<li><a href="http://gotocon.com/video#18">Democratising attention data
at guardian.co.uk</a>. Graham Tackley, GOTO Aarhus 2013</li>

<li><a href="http://gotocon.com/video#6">Functional Reactive
Programming with RxJava</a>. Ben Christensen, GOTO Aarhus 2013
(registration required).</li>

<li><a href="http://www.infoq.com/presentations/Breaking-the-Monolith">Breaking
the Monolith</a>. Stefan Tilkov, May 2012.</li>
</ul>

<p>Papers</p>

<ul>
<li>L. Lamport, "The Implementation of Reliable Distributed
Multiprocess Systems", 1978 http://
research.microsoft.com/en-us/um/people/lamport/pubs/implementation.pdf</li>

<li>L. Lamport, R. Shostak, M. Pease, "The Byzantine Generals
Problem", 1982 (available at) http://
www.cs.cornell.edu/courses/cs614/2004sp/papers/lsp82.pdf</li>

<li>R.T. Fielding, "Architectural Styles and the Design of
Network-based Software Architectures", 2000
http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm</li>

<li>E. A. Brewer, "Towards Robust Distributed Systems", 2000
http://www.cs.berkeley.edu/ ~brewer/cs262b-2004/PODC-keynote.pdf</li>

<li>E. Brewer, "CAP Twelve Years Later: How the 'Rules' Have Changed",
2012, http://
www.infoq.com/articles/cap-twelve-years-later-how-the-rules-have-changed</li>
</ul>
</section>

<section id="further-reading">
<h2>Further Reading</h2>

<p><a href="https://martinfowler.com/microservices"><img src="microservices_files/microservices-sq.png"></a>The above list captures the references we used when we originally
  wrote this article in early 2014. For an up to date list of sources
  for more information, take a look at the <a href="https://martinfowler.com/microservices">Microservice Resource Guide</a>.</p>
</section>
</div>

<div class="appendix">
<details id="SignificantRevisions">
<summary>Significant Revisions</summary>

<p><i>25 March 2014: </i>last installment on are microservices the future?</p>

<p><i>24 March 2014: </i>added section on evolutionary design</p>

<p><i>19 March 2014: </i>added sections on infrastructure
  automation and design for failure</p>

<p><i>18 March 2014: </i>added section on decentralized data</p>

<p><i>17 March 2014: </i>added section on decentralized governance</p>

<p><i>14 March 2014: </i>added section on smart endpoint and dumb pipes</p>

<p><i>13 March 2014: </i>added section on products not projects</p>

<p><i>12 March 2014: </i>added section on organizing around
  business capabilities</p>

<p><i>10 March 2014: </i>published first installment</p>
</details>
</div>
</main>

<nav id="bottom-navmenu" style="display: none;">
<nav class="navmenu">
<div class="nav-head">  <div class="search">
    <!-- SiteSearch Google -->
    <form method="GET" action="https://www.google.com/search">
      <input type="hidden" name="ie" value="UTF-8">
      <input type="hidden" name="oe" value="UTF-8">
      <input class="field" type="text" name="q" size="15" maxlength="255">
      <button class="button" type="submit" name="btnG" value=" " title="Search">
      <input type="hidden" name="domains" value="martinfowler.com">
      <input type="hidden" name="sitesearch" value=""> 
      <input type="hidden" name="sitesearch" value="martinfowler.com">
    
  </button></form></div>

<div class="closediv">
<span class="close" title="close"></span>
</div>
</div>

<div class="nav-body">
<div class="topics">
<h2>Topics</h2>

<p><a href="https://martinfowler.com/architecture">Architecture</a></p>

<p><a href="https://refactoring.com/">Refactoring</a></p>

<p><a href="https://martinfowler.com/agile.html">Agile</a></p>

<p><a href="https://martinfowler.com/delivery.html">Delivery</a></p>

<p><a href="https://martinfowler.com/microservices">Microservices</a></p>

<p><a href="https://martinfowler.com/data">Data</a></p>

<p><a href="https://martinfowler.com/testing">Testing</a></p>

<p><a href="https://martinfowler.com/dsl.html">DSL</a></p>
</div>

<div class="about">
<h2>about me</h2>

<p><a href="https://martinfowler.com/aboutMe.html">About</a></p>

<p><a href="https://martinfowler.com/books">Books</a></p>

<p><a href="https://martinfowler.com/faq.html">FAQ</a></p>
</div>

<div class="content">
<h2>content</h2>

<p><a href="https://martinfowler.com/videos.html">Videos</a></p>

<p><a href="https://martinfowler.com/tags">Content Index</a></p>

<p><a href="https://martinfowler.com/articles/eurogames">Board Games</a></p>

<p><a href="https://martinfowler.com/photos">Photography</a></p>
</div>

<div class="tw">
<h2>Thoughtworks</h2>

<p><a href="https://thoughtworks.com/insights">Insights</a></p>

<p><a href="https://thoughtworks.com/careers">Careers</a></p>

<p><a href="https://thoughtworks.com/products">Products</a></p>
</div>

<div class="feeds">
<h2>follow</h2>

<p><a href="https://www.twitter.com/martinfowler">Twitter</a></p>

<p><a href="https://martinfowler.com/feed.atom">RSS</a></p>

<p><a href="https://toot.thoughtworks.com/@mfowler">Mastodon</a></p>
</div>
</div>
</nav>
</nav>
<footer id="page-footer">
<div class="tw-logo">
<a href="http://www.thoughtworks.com/">
<img src="../thoughtworks_white.png">
</a>
</div>
<div class="menu-button">
<div class="icon-bars navmenu-button"></div>
</div>
<div class="copyright">
<p>© Martin Fowler | <a href="http://www.thoughtworks.com/privacy-policy">Privacy Policy</a> | <a href="https://martinfowler.com/aboutMe.html#disclosures">Disclosures</a></p>
</div>
</footer>
<!-- Google Analytics -->
<!-- old Google Universal -->
<script>
window.ga=window.ga||function(){(ga.q=ga.q||[]).push(arguments)};ga.l=+new Date;
ga('create', 'UA-17005812-1', 'auto');
ga('send', 'pageview');
</script>
<script async="" src="../analytics.js"></script>
<!-- New Google GA4 -->
<!-- global site tag (gtag.js) - Google Analytics -->
<script async="" src="../js"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'G-6D51F4BDVF');
</script>
<!-- End Google Analytics -->



<script src="../jquery-3.5.1.min.js" type="text/javascript"></script>

<script src="../mfcom.js" type="text/javascript"></script>


</body><div id="transmart-crx-shadow-root" style="all: initial;"></div></html>